
#include <cstdio>
#include <BPainter>
#include <BMouseEvent>

#include "PolygonItem.h"

PolygonItem::PolygonItem(BGraphicItem* parent) : BGraphicItem(parent)
{
	_dirty = false;
}
PolygonItem::~PolygonItem()
{

}

void PolygonItem::appendPoint(const BPointf& point)
{
	_originPoints.append(point);
	_dirty = true;
	this->fresh();
}
void PolygonItem::insertPoint(int index, const BPointf& point)
{
	_originPoints.insert(index, point);
	_dirty = true;
	this->fresh();
}
void PolygonItem::removePoint(int index)
{
	_originPoints.remove(index);
	_dirty = true;
	this->fresh();
}
void PolygonItem::clearPoints()
{
	_originPoints.clear();
	_dirty = true;
	this->fresh();
}

const BPointfArray& PolygonItem::points() const
{
	return _originPoints;
}

void PolygonItem::clearPolygons()
{
	_polygons.clear();
	_points.clear();
}
int PolygonItem::splitPolygons()
{
	_points = _originPoints;
	_crossPoints.clear();
	bool intersect = false;
	for (int i = 0; i < _points.size() - 1; i++)
	{
		BLine2f line(_points[i], _points[i + 1]);
		BPointf phit;
		int end = i + 1;
		while (++end < _points.size() - 1)
		{
			BLine2f after(_points[end], _points[end + 1]);
			if (intersect = line.intersect(after, phit))
				break;
		}
		if (intersect)
		{
			_crossPoints[phit.length2()].set(i, phit);
		}
	}
	//if (!intersect)
	//{
	//	_polygons.append().append(_points);
	//	break;
	//}
	return _polygons.size();
}

void PolygonItem::paint(BPainter& painter)
{
	BGraphicItem::paint(painter);

	if (_originPoints.size())
	{
		painter.setColor(0, 200, 0);
		for (int p = 0; p < _polygons.size(); p++)
		{
			const BPolygon2f& polygon = _polygons[p];
			const BIntArray& indices = polygon.trigIndices();
			for (int i = 0; i < indices.size(); i += 3)
			{
				int ia = indices[i];
				int ib = indices[i + 1];
				int ic = indices[i + 2];
				painter.fillTriangle(polygon[ia], polygon[ib], polygon[ic]);
			}
		}

		painter.setColor(Color_Wire);
		painter.drawPolygon(_originPoints);

		painter.setColor(200, 0, 0);
		painter.drawPolygon(_points);

		painter.setColor(200, 0, 200);
		painter.setPointSmooth(true);
		painter.setPointSize(3);
		for (auto it = _crossPoints.begin(); it != _crossPoints.end(); it++)
		{
			const BPointf& point = (*it).value();
			painter.drawPoint(point);
			painter.drawText(point + 3, it.index());
		}
	}
}

void PolygonItem::freshEvent(const BEvent& event)
{
	if (_dirty)
	{
		_dirty = false;
	}
}

void PolygonItem::mouseMoveEvent(const BMouseEvent& mouseEvent)
{

}
void PolygonItem::mouseClickEvent(const BMouseEvent& mouseEvent)
{
	const BPointf pos = mouseEvent.pos();
	_originPoints.append(pos);
	_dirty = true;
	this->fresh();
}
